import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.bouncycastle.crypto.digests.RIPEMD160Digest;


public class Crypt {
	public static final int ALGORITHM_RIPEMD160 = 1;
	public static final int ALGORITHM_SHA1 = 2;
	
	public static byte[] getPBKDF2(byte salt[], byte text[], int iterationCount, int algorithm){
		byte b[]=ByteBuffer.allocate(4).putInt(1).array();
		
		byte ret[]=null;
		for (int i=0;i<iterationCount;i++){
			if (i==0){
				salt=getHMAC(Util.concatArray(salt, b, salt.length+b.length), text, algorithm);
				ret=salt;
			}else{
				salt=getHMAC(salt, text, algorithm);
				
				for (int x=0;x<salt.length;x++){
					ret[x]^=salt[x];
				}
			}
		}
		
		return ret;
	}
	
	
	
	public static byte[] getHMAC(byte salt[], byte text[], int algorithm){
		if (text.length > 64){
			text=getHash(text, algorithm);
		}
	    
		byte ipad[]=new byte[64];
		byte opad[]=new byte[64];
		
		for(int i=0;i<64;i++){ 
			if (i<text.length){
				ipad[i] = (byte) (text[i] ^ 0x36363636);
				opad[i] = (byte) (text[i] ^ 0x5C5C5C5C);
			}else{
				ipad[i] = (byte) (0^ 0x36363636);
				opad[i] = (byte) (0 ^ 0x5C5C5C5C);
			}
		}
		
		byte hash[]=getHash(Util.concatArray(ipad, salt, ipad.length+salt.length), algorithm);
		hash=getHash(Util.concatArray(opad, hash, opad.length+hash.length), algorithm);
		return hash;
	}
	
	/**
	 * 
	 * @param text
	 * @param algorithm
	 * @return hash of text in given algorithm
	 */
	private static byte[] getHash(byte text[], int algorithm){
		byte ret[]=null;
		switch (algorithm) {
			case ALGORITHM_RIPEMD160:
				ret=getRIPEMD160(text);
				break;
					
			case ALGORITHM_SHA1:
				ret=getSHA1(text);
				break;
	
			default:
				throw new RuntimeException("Unknow algorithm. Use ALGORITHM_* constants");
			}
		return ret;
	}
	
	
	/**
	 * 
	 * @param text 
	 * @return RIPEMD160 hash of text
	 */
	
	public static byte[] getRIPEMD160(byte text[]){
		RIPEMD160Digest d = new RIPEMD160Digest();
        d.update (text, 0, text.length);
        byte ret[]=new byte[d.getDigestSize()];
        d.doFinal(ret, 0);
        return ret;
	}
	/**
	 * 
	 * @param text
	 * @return SHA1 hash of text
	 */
	public static byte[] getSHA1(byte text[]){
	    MessageDigest md = null;
		try {
	        md = MessageDigest.getInstance("SHA-1");
	    }
	    catch(NoSuchAlgorithmException e) {
	        e.printStackTrace();
	    } 
	    return md.digest(text);
	    
	}
	
	
	
}
